/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2018, Open Source Geospatial Foundation (OSGeo)
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.data.hana;

import java.sql.Connection;
import org.geotools.jdbc.JDBCPrimaryKeyTestSetup;
import org.geotools.jdbc.JDBCTestSetup;

/** @author Stefan Uhrig, SAP SE */
public class HanaPrimaryKeyTestSetup extends JDBCPrimaryKeyTestSetup {

    private static final String AUTO_TABLE = "auto";

    private static final String MULTI_TABLE = "multi";

    private static final String NONINC_TABLE = "noninc";

    private static final String SEQ_TABLE = "seq";

    private static final String NONFIRST_TABLE = "nonfirst";

    private static final String UNIQ_TABLE = "uniq";

    private static final String NOKEY_TABLE = "nokey";

    public HanaPrimaryKeyTestSetup(JDBCTestSetup delegate) {
        super(delegate);
    }

    @Override
    protected void createAutoGeneratedPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {
                {"key", "INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY"},
                {"name", "VARCHAR(255)"},
                {"geom", "ST_Geometry(1000004326)"}
            };
            htu.createTestTable(AUTO_TABLE, cols);

            htu.insertFieldsIntoTable(htu.getTestSchema(), AUTO_TABLE, "name", "geom", "one", null);
            htu.insertFieldsIntoTable(htu.getTestSchema(), AUTO_TABLE, "name", "geom", "two", null);
            htu.insertFieldsIntoTable(
                    htu.getTestSchema(), AUTO_TABLE, "name", "geom", "three", null);
        }
    }

    @Override
    protected void createMultiColumnPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {
                {"key1", "INT NOT NULL"},
                {"key2", "VARCHAR(255) NOT NULL"},
                {"name", "VARCHAR(255)"},
                {"geom", "ST_Geometry(1000004326)"}
            };
            htu.createTestTable(MULTI_TABLE, cols);
            htu.addPrimaryKey(htu.getTestSchema(), MULTI_TABLE, "key1", "key2");

            htu.insertIntoTestTable(MULTI_TABLE, 1, "x", "one", null);
            htu.insertIntoTestTable(MULTI_TABLE, 2, "y", "two", null);
            htu.insertIntoTestTable(MULTI_TABLE, 3, "z", "three", null);
        }
    }

    @Override
    protected void createNonIncrementingPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {
                {"key", "INT PRIMARY KEY"},
                {"name", "VARCHAR(255)"},
                {"geom", "ST_Geometry(1000004326)"}
            };
            htu.createTestTable(NONINC_TABLE, cols);

            htu.insertIntoTestTable(NONINC_TABLE, 1, "one", null);
            htu.insertIntoTestTable(NONINC_TABLE, 2, "two", null);
            htu.insertIntoTestTable(NONINC_TABLE, 3, "three", null);
        }
    }

    @Override
    protected void createSequencedPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {
                {"key", "INT PRIMARY KEY"},
                {"name", "VARCHAR(255)"},
                {"geom", "ST_Geometry(1000004326)"}
            };
            htu.createRegisteredTestTable(SEQ_TABLE, cols);

            htu.skipSequenceValueFor(htu.getTestSchema(), SEQ_TABLE, "key");
            htu.insertIntoTestTable(
                    SEQ_TABLE, htu.nextTestSequenceValueForColumn(SEQ_TABLE, "key"), "one", null);
            htu.insertIntoTestTable(
                    SEQ_TABLE, htu.nextTestSequenceValueForColumn(SEQ_TABLE, "key"), "two", null);
            htu.insertIntoTestTable(
                    SEQ_TABLE, htu.nextTestSequenceValueForColumn(SEQ_TABLE, "key"), "three", null);
        }
    }

    @Override
    protected void createNullPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {{"name", "VARCHAR(255)"}};
            htu.createTestTable(NOKEY_TABLE, cols);

            htu.insertIntoTestTable(NOKEY_TABLE, "one");
            htu.insertIntoTestTable(NOKEY_TABLE, "two");
            htu.insertIntoTestTable(NOKEY_TABLE, "three");
        }
    }

    @Override
    protected void createUniqueIndexTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {
                {"key", "INT"}, {"name", "VARCHAR(255)"}, {"geom", "ST_Geometry(1000004326)"}
            };
            htu.createTestTable(UNIQ_TABLE, cols);

            htu.addUniqueIndex(htu.getTestSchema(), UNIQ_TABLE, "uniq_key_index", "key");
            htu.insertIntoTestTable(UNIQ_TABLE, 1, "one", null);
            htu.insertIntoTestTable(UNIQ_TABLE, 2, "two", null);
            htu.insertIntoTestTable(UNIQ_TABLE, 3, "three", null);
        }
    }

    @Override
    protected void createNonFirstColumnPrimaryKey() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.createTestSchema();

            String[][] cols = {
                {"name", "VARCHAR(255)"},
                {"key", "INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY"},
                {"geom", "ST_Geometry(1000004326)"}
            };
            htu.createTestTable(NONFIRST_TABLE, cols);

            htu.insertFieldsIntoTable(
                    htu.getTestSchema(), NONFIRST_TABLE, "name", "geom", "one", null);
            htu.insertFieldsIntoTable(
                    htu.getTestSchema(), NONFIRST_TABLE, "name", "geom", "two", null);
            htu.insertFieldsIntoTable(
                    htu.getTestSchema(), NONFIRST_TABLE, "name", "geom", "three", null);
        }
    }

    @Override
    protected void dropAutoGeneratedPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropTestTableCascade(AUTO_TABLE);
        }
    }

    @Override
    protected void dropMultiColumnPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropTestTableCascade(MULTI_TABLE);
        }
    }

    @Override
    protected void dropNonIncrementingPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropTestTableCascade(NONINC_TABLE);
        }
    }

    @Override
    protected void dropSequencedPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropSequence(htu.getTestSchema(), "SEQ_KEY_SEQUENCE");
            htu.dropTestTableCascade(SEQ_TABLE);
        }
    }

    @Override
    protected void dropNullPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropTestTableCascade(NOKEY_TABLE);
        }
    }

    @Override
    protected void dropUniqueIndexTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropTestTableCascade(UNIQ_TABLE);
        }
    }

    @Override
    protected void dropNonFirstPrimaryKeyTable() throws Exception {
        try (Connection conn = getConnection()) {
            HanaTestUtil htu = new HanaTestUtil(conn, fixture);
            htu.dropTestTableCascade(NONFIRST_TABLE);
        }
    }
}
